﻿using System;
using System.Reflection;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Caches.SysCache;
using NHibernate.Tool.hbm2ddl;

namespace SportStore.Core.NHibernate
{

    /// <summary>
    /// Configures an NHibernate session factory and exposes the instance
    /// </summary>
    public class SessionFactoryBuilder : ISessionFactoryBuilder
    {
        #region Constants and Fields

        private ISessionFactory sessionFactory;

        #endregion

        #region ISessionFactoryBuilder

        /// <summary>
        /// Gets an instance of a configured session factory.
        /// </summary>
        public ISessionFactory CreateSessionFactory()
        {
            if (this.sessionFactory == null)
            {
                var assembly = Assembly.Load("SportStore.Data");

                var config = Fluently.Configure()
                    .Database(MsSqlConfiguration.MsSql2005
                        .ConnectionString(c => c.FromConnectionStringWithKey("SportStoreDb"))
                        .DefaultSchema("dbo")
                        .Cache(c => c.UseQueryCache().ProviderClass<SysCacheProvider>())
                        .Raw("prepare_sql", "true"))
                    .ExposeConfiguration(cfg => cfg.SetProperty("adonet.batch_size", "10"))
                    .Mappings(m => { m.FluentMappings.AddFromAssembly(assembly); m.HbmMappings.AddFromAssembly(assembly); })
                    .BuildConfiguration();

                // Ensure columns and tables are quoted correctly
                SchemaMetadataUpdater.QuoteTableAndColumns(config);

                this.sessionFactory = config.BuildSessionFactory();
            }

            return this.sessionFactory;
        }

        #endregion
    }
}
